package com.gagakuai.bpm.config.redis;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.gagakuai.bpm.domian.dto.camunda.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.util.Assert;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/*
 * Redis操作对象
 */
public class ObjectRedisTemplate<V> extends RedisTemplate<String, V> {

    @Autowired
    public ObjectRedisTemplate(final LettuceConnectionFactory redisConnectionFactory) {
        StringRedisSerializer string = new StringRedisSerializer();
       // RedisSerializer<V> object = new ObjectSerializer<>();

        //序列化
        FastJsonRedisSerializer<UserInfo> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(UserInfo.class);

        setEnableDefaultSerializer(true);
        setDefaultSerializer(string);
        setKeySerializer(string);
        setValueSerializer(fastJsonRedisSerializer);
        setHashKeySerializer(string);
        setHashValueSerializer(fastJsonRedisSerializer);
        setConnectionFactory(redisConnectionFactory);
        afterPropertiesSet();
    }


    /*
     * Value 序列化
     *
     * @param <T>
     * @author /
     */
    private static class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

        private final Class<T> clazz;

        FastJsonRedisSerializer(Class<T> clazz) {
            super();
            this.clazz = clazz;
        }

        @Override
        public byte[] serialize(T t) {
            if (t == null) {
                return new byte[0];
            }
            return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8);
        }

        @Override
        public T deserialize(byte[] bytes) {
            if (bytes == null || bytes.length <= 0) {
                return null;
            }
            String str = new String(bytes, StandardCharsets.UTF_8);
            str = str.replace("\"@type\":\"com.hx.module.security.domain.dto.OnlineUserDTO\",", "");
            return JSON.parseObject(str, clazz);
        }

    }

    /*
     * 重写序列化器
     *
     * @author /
     */
    private static class StringRedisSerializer implements RedisSerializer<Object> {

        private final Charset charset;

        StringRedisSerializer() {
            this(StandardCharsets.UTF_8);
        }

        private StringRedisSerializer(Charset charset) {
            Assert.notNull(charset, "Charset must not be null!");
            this.charset = charset;
        }

        @Override
        public String deserialize(byte[] bytes) {
            return (bytes == null ? null : new String(bytes, charset));
        }

        @Override
        public byte[] serialize(Object object) {
            String string = JSON.toJSONString(object);
            if (StringUtils.isBlank(string)) {
                return null;
            }
            string = string.replace("\"", "");
            return string.getBytes(charset);
        }
    }

}